import 'dart:async';

import 'package:fish_redux/fish_redux.dart';
import 'package:flutter/material.dart' hide Action;
import 'package:flutter/widgets.dart' hide Action;
import 'package:toast/toast.dart';
import 'package:www.znpigai.teacher/global_store/state.dart';
import 'package:www.znpigai.teacher/utils/http.dart';
import 'package:www.znpigai.teacher/utils/nav.dart';
import 'package:www.znpigai.teacher/utils/progress_dialog.dart';
import 'package:www.znpigai.teacher/utils/util.dart';
import 'package:fluwx/fluwx.dart' as fluwx;

import 'action.dart';
import 'state.dart';

Effect<LoginState> buildEffect() {
  return combineEffects(<Object, Effect<LoginState>>{
    LoginAction.onConfirm: _onConfirm,
    LoginAction.onWxLogin: _onWxLogin,
    LoginAction.onRegister: _onRegister,
    LoginAction.onReset: _onReset,
    LoginAction.onVerifyCode: _onVerifyCode,
    LoginAction.onAgreement: _onAgreement,
  });
}

void _onConfirm(Action action, Context<LoginState> ctx) async {
  String account = ctx.state.accountController.text;
  switch (ctx.state.mode) {
    case LoginMode.REGISTER:
    case LoginMode.RESET:
      if (account.isEmpty) {
        Toast.show("请输入手机号", ctx.context);
        return;
      }
      if (ctx.state.password.isEmpty) {
        Toast.show("请输入密码", ctx.context);
        return;
      }
      if (ctx.state.code.isEmpty) {
        Toast.show("请输入验证码", ctx.context);
        return;
      }
      break;
    case LoginMode.CHANGE_MOBILE:
      if (account.isEmpty) {
        Toast.show("请输入手机号", ctx.context);
        return;
      }
      if (ctx.state.code.isEmpty) {
        Toast.show("请输入验证码", ctx.context);
        return;
      }
      break;
    case LoginMode.LOGIN:
      if (account.isEmpty) {
        Toast.show("请输入手机号", ctx.context);
        return;
      }
      if (ctx.state.password.isEmpty) {
        Toast.show("请输入密码", ctx.context);
        return;
      }
      break;
  }

  switch (ctx.state.mode) {
    case LoginMode.REGISTER:
      _register(ctx);
      break;
    case LoginMode.LOGIN:
      _login(ctx.context, account, ctx.state.password);
      break;
    case LoginMode.RESET:
      _resetPassword(ctx);
      break;
    case LoginMode.CHANGE_MOBILE:
      _startCountdownTimer(ctx, MAX);
      var pr = new ProgressDialog(ctx.context)..setMessage('请等待...');
      pr.show();
      var url = '/correct/${GlobalState.userRole}/api/mobile/update.mvc';
      HttpResult result = await Http.post(url,
          data: {'mobile': account, 'smscode': ctx.state.code});
      pr.hide();
      if (result.success) {
        Navigator.of(ctx.context).pop(account);
      } else {
        _cancelTimer(ctx);
        Toast.show(result.errorMsg, ctx.context);
      }
      break;
  }
}

void _register(Context<LoginState> ctx) async {
  String account = ctx.state.accountController.text;
  if (ctx.state.code.isEmpty) {
    Util.alert("请输入验证码", ctx.context);
    return;
  }

  if (account.isEmpty) {
    Util.alert("请输入用户名", ctx.context);
    return;
  }

  if (ctx.state.password.isEmpty) {
    Util.alert("请输入密码", ctx.context);
    return;
  }

  var pr = new ProgressDialog(ctx.context)..setMessage('请等待...');
  pr.show();
  var url = '/correct/join/api/${GlobalState.userRole}/reg.mvc';
  HttpResult result = await Http.post(url, data: {
    'mobile': account,
    'smscode': ctx.state.code,
    'password': ctx.state.password,
    'name': ctx.state.nameController.text,
    'sex': ctx.state.ganderValue,
  });
  pr.hide();
  if (result.success) {
    GlobalState.isSignIn = true;
    Navigator.of(ctx.context)
        .pushNamedAndRemoveUntil(Nav.HOME, (Route<dynamic> route) => false);
  } else {
    Toast.show(result.errorMsg, ctx.context);
  }
}

void _resetPassword(Context<LoginState> ctx) async {
  String account = ctx.state.accountController.text;
  var pr = new ProgressDialog(ctx.context)..setMessage('请等待...');
  pr.show();
  var url = '/correct/join/api/pwd/reset.mvc';
  HttpResult result = await Http.post(url, data: {
    'mobile': account,
    'smscode': ctx.state.code,
    'pwd': ctx.state.password,
    'isteacher': true,
  });
  pr.hide();
  if (result.success) {
    GlobalState.isSignIn = true;
    Navigator.of(ctx.context)
        .pushNamedAndRemoveUntil(Nav.HOME, (Route<dynamic> route) => false);
  } else {
    Toast.show(result.errorMsg, ctx.context);
  }
}

void _onWxLogin(Action action, Context<LoginState> ctx) async {
  fluwx.responseFromAuth.listen((response) async {
    if (response.errCode == 0) {
      var pr = new ProgressDialog(ctx.context)..setMessage('请等待...');
      pr.show();
      HttpResult result =
          await Http.post("/correct/join/api/third/login.mvc", data: {
        'loginType': 'wx',
        'identity': 'STUDENT',
        'code': response.code,
      });
      pr.hide();

      if (result.success) {
        GlobalState.ticket = result.data;
        GlobalState.isSignIn = true;
        Navigator.of(ctx.context)
            .pushNamedAndRemoveUntil(Nav.HOME, (Route<dynamic> route) => false);
      } else {
        Util.alertFail(result, ctx.context);
      }
    }
  });
  fluwx.sendAuth(scope: "snsapi_userinfo", state: "wechat_sdk_demo_test");
}

void _onRegister(Action action, Context<LoginState> ctx) {
  Navigator.of(ctx.context)
      .pushNamed('login', arguments: {"mode": LoginMode.REGISTER});
}

void _onReset(Action action, Context<LoginState> ctx) {
  Navigator.of(ctx.context)
      .pushNamed('login', arguments: {"mode": LoginMode.RESET});
}

void _onVerifyCode(Action action, Context<LoginState> ctx) async {
  String account = ctx.state.accountController.text;
  if (account.length != 11) {
    Toast.show("请输入正确的手机号", ctx.context,
        duration: Toast.LENGTH_LONG, gravity: Toast.BOTTOM);
    return;
  }

  _startCountdownTimer(ctx, MAX);
  var pr = new ProgressDialog(ctx.context)..setMessage('请等待...');
  pr.show();
  _sendSms(ctx.state, account).then((result) {
    pr.hide();
    if (result.success) {
      Toast.show('验证码发送成功', ctx.context);
    } else {
      _cancelTimer(ctx);
      Toast.show(result.errorMsg, ctx.context);
    }
  });
}

void _onAgreement(Action action, Context<LoginState> ctx) {
  var url = "/correct/pub/view/agreement.mvc?type=${action.payload}";
  Navigator.of(ctx.context).pushNamed(Nav.WEB_PAGE, arguments: {"url": url});
}

Timer _timer;
var _counter = 0;
const MAX = 10;

void _startCountdownTimer(Context<LoginState> ctx, max) {
  const oneSec = const Duration(seconds: 1);

  var callback = (timer) {
    if (ctx.isDisposed) {
      _timer.cancel();
      return;
    }

    ctx.dispatch(LoginActionCreator.onCountDown(_counter));
    if (_counter == 0) {
      _timer.cancel();
    } else {
      _counter -= 1;
    }
  };

  _counter = max;
  ctx.dispatch(LoginActionCreator.onCountDown(_counter));
  _counter -= 1;

  _timer = Timer.periodic(oneSec, callback);
}

void _cancelTimer(Context<LoginState> ctx) {
  _timer.cancel();
  _counter = 0;
  ctx.dispatch(LoginActionCreator.onCountDown(0));
}

Future<HttpResult> _sendSms(LoginState state, String mobile) async {
  String type = "";
  switch (state.mode) {
    case LoginMode.REGISTER:
      type = 'TYPE_REG';
      break;
    case LoginMode.LOGIN:
      type = 'TYPE_LOGIN';
      break;
    case LoginMode.RESET:
    case LoginMode.CHANGE_MOBILE:
      type = 'TYPE_FIND_PWD';
      break;
  }

  var url = '/correct/join/api/sms/code/get.mvc';
  final _param = {'type': type, 'mobile': mobile};
  return await Http.get(url, query: _param);
}

void _login(BuildContext context, String username, String password) {
  var pr = new ProgressDialog(context)..setMessage('请等待...');
  pr.show();

  var url = '/correct/join/api/login.mvc';
  final _param = {
    'uname': username,
    'pwd': password,
    't': GlobalState.isTeacher ? '' : '0'
  };
  Http.post(url, data: _param).then((result) {
    pr.hide();
    if (result.success) {
      GlobalState.isSignIn = true;
      Navigator.of(context)
          .pushNamedAndRemoveUntil(Nav.HOME, (Route<dynamic> route) => false);
    } else {
      Util.alert(result.errorMsg, context);
    }
  });
}
